﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ACP.Business;
using ACP.DTO;
using System.Web.Security;

namespace ACP.Web.UI
{
    public partial class Test : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                int examTypeID = 1;
                int examID = 1;
                if (!String.IsNullOrEmpty(Request.QueryString["tid"]))
                {
                    examTypeID = Convert.ToInt32(Request.QueryString["tid"]);

                }
                if (!String.IsNullOrEmpty(Request.QueryString["eid"]))
                {
                    examID = Convert.ToInt32(Request.QueryString["eid"]);

                }

               

                if (!IsPostBack)
                {
                    System.Web.Security.MembershipUser user = Membership.GetUser();

                    if (user == null)
                    {
                        string strQueryStringPrms = "ReturnUrl=~/test.aspx?tid=" + examTypeID + "%26eid%3D" + examID;
                        Response.Redirect("/account/login.aspx?" + strQueryStringPrms, false);
                    }
                    else
                    {
                        if (!String.IsNullOrEmpty(user.UserName))
                        {

                            Guid aspnetUserGuid = UsersLogic.GetuserGuidByUserName(user.UserName);
                            user loggedInuser = UsersLogic.GetuserByGuid(aspnetUserGuid);
                            examtype _examType = ExamTypeLogic.GetExamType(examTypeID); //by default sample test will be loaded (assgned 1 as sample)
                            //Session["examStart"] created for preventing F5 and Ctrl + F5
                            if (loggedInuser != null && Session["examStart"] == null)
                            {
                                Session["userId"] = loggedInuser.userid;
                                Session["examStart"] = true;

                                BindQuestions(loggedInuser.userid, _examType.noofquestions, _examType.examtypeid,examID);
                                DateTime setExamTime = DateTime.Now.AddSeconds(Convert.ToDouble(_examType.examduration * 60));
                                GetRemainingTime(setExamTime);
                                Session["time"] = setExamTime;
                            }
                            else
                            {
                                lblAlertMessage.Text = "Please continue or Finish the current exam to start a new one!! ";
                                //BindQuestions(loggedInuser.userid, _examType.noofquestions, _examType.examtypeid);
                                List<ExamInformation> lstQuestions;
                                lstQuestions = (List<ExamInformation>)Session["QuestionsList"];
                                int intCurrentQuestion = (int)Session["currentQuestion"];
                                //Session["testId"] = newExam.testid;
                                NavigateQuestions(lstQuestions, intCurrentQuestion);

                            }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    ErrorMessage = ex.Message,
                    ErrorFunction = "Page_Load",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }


        }

        private void ClearControls()
        {
            rdbOptions.Items.Clear();
            chkOptions.Items.Clear();
            udpQuestions.Update();
        }

        protected void UpdateTimer_Tick(object sender, EventArgs e)
        {
            if (Session["time"] != null)
            {
                DateTime setExamTime = (DateTime)Session["time"];
                GetRemainingTime(setExamTime);
            }

        }

        private void GetRemainingTime(DateTime setExamTime)
        {
            try
            {
                TimeSpan time1 = new TimeSpan();
                time1 = setExamTime - DateTime.Now;
                if (time1.Seconds <= 0 && time1.Minutes <= 0 && time1.Hours <= 0)
                {
                    DateStampLabel.Text = "TimeOut!";
                    if (Session["testId"] != null)
                    {
                        int testId = Convert.ToInt32(Session["testId"]);
                        InsertExamResult(testId);
                        Session.Remove("examStart");
                        Session["examStart"] = null;
                        Response.Redirect("Result.aspx", false);
                    }
                }
                else
                {
                    string hours = time1.Hours < 10 ? "0" + time1.Hours.ToString() : time1.Hours.ToString();
                    string minitues = time1.Minutes < 10 ? "0" + time1.Minutes.ToString() : time1.Minutes.ToString();
                    string seconds = time1.Seconds < 10 ? "0" + time1.Seconds.ToString() : time1.Seconds.ToString();
                    DateStampLabel.Text = hours + ":" + minitues + ":" + seconds;
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "GetRemainingTime()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }

        }

        private void BindQuestions(int loggedInUserId, int noOfQuestions, int exampTypeId,int examID)
        {
            try
            {

                result newExam = new result()
                {
                    uid = loggedInUserId,
                    examtypeid = exampTypeId, //TBD
                    dateofstarttest = DateTime.Now
                };
                List<ExamInformation> lstQuestions = QuestionsLogic.GetRandomQuestions(ref newExam, noOfQuestions, newExam.uid, examID);
                Session["QuestionsList"] = lstQuestions;
                Session["testId"] = newExam.testid;
                NavigateQuestions(lstQuestions, 1);
                btnPrevious.Enabled = false;
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "BindQuestions()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }

        }

        private void NavigateQuestions(List<ExamInformation> lstQuestions, int questionNumber)
        {
            try
            {

                if (lstQuestions != null)
                {

                    //Get the CurrentQuestion information
                    ExamInformation examInfo = lstQuestions.Where(q => q.SerialNumber == questionNumber).FirstOrDefault();

                    //Assign Question content literal control
                    Literal ltrlQuestion = new Literal();
                    ltrlQuestion.Text = examInfo.SerialNumber.ToString() + ". " + examInfo.Question + "<br />";

                    //Add the Literal control to Place holder
                    plcQuestionAnswer.Controls.Add(ltrlQuestion);

                    hdnQuestionSerialNo.Value = examInfo.SerialNumber.ToString();

                    //Clear the previous questions options from Radio button list or Chekbox list
                    ClearControls();


                    if (examInfo.QuestionType == "S")
                    {
                        //Assign values from db to Radio button options for current questions
                        rdbOptions.Items.Add(new ListItem(examInfo.Option1, "A"));
                        rdbOptions.Items.Add(new ListItem(examInfo.Option2, "B"));
                        if (examInfo.Option3 != null) rdbOptions.Items.Add(new ListItem(examInfo.Option3, "C"));
                        if (examInfo.Option4 != null) rdbOptions.Items.Add(new ListItem(examInfo.Option4, "D"));
                        if (examInfo.Option5 != null) rdbOptions.Items.Add(new ListItem(examInfo.Option5, "E"));

                        //If user has already selected the Answer
                        if (examInfo.SelectedAnswer != null)
                        {
                            rdbOptions.SelectedValue = examInfo.SelectedAnswer;
                        }
                        pnlRadioOptions.Visible = true;
                        pnlChkOptions.Visible = pnlChkOptions.Visible ? false : true;
                        Session["currentQuestion"] = examInfo.SerialNumber;
                    }
                    else
                    {
                        //Assign values from db to Checkbox list options for current questions
                        chkOptions.Items.Add(new ListItem(examInfo.Option1, "A"));
                        chkOptions.Items.Add(new ListItem(examInfo.Option2, "B"));
                        if (examInfo.Option3 != null) chkOptions.Items.Add(new ListItem(examInfo.Option3, "C"));
                        if (examInfo.Option4 != null) chkOptions.Items.Add(new ListItem(examInfo.Option4, "D"));
                        if (examInfo.Option5 != null) chkOptions.Items.Add(new ListItem(examInfo.Option5, "E"));

                        if (examInfo.SelectedAnswer != null)
                        {
                            char[] selectedAnswers = examInfo.SelectedAnswer.ToCharArray().Where(c => c != ',').ToArray();
                            for (int i = 0; i < selectedAnswers.Count(); i++)
                            {
                                switch (selectedAnswers[i])
                                {
                                    case 'A': chkOptions.Items[0].Selected = true;
                                        break;
                                    case 'B': chkOptions.Items[1].Selected = true;
                                        break;
                                    case 'C': chkOptions.Items[2].Selected = true;
                                        break;
                                    case 'D': chkOptions.Items[3].Selected = true;
                                        break;
                                    case 'E': chkOptions.Items[4].Selected = true;
                                        break;
                                    default: break;
                                }
                            }

                        }
                        pnlChkOptions.Visible = true;
                        pnlRadioOptions.Visible = pnlRadioOptions.Visible ? false : true;
                        //plcQuestionAnswer.Controls.Add(chkOptions);
                        Session["currentQuestion"] = examInfo.SerialNumber;
                    }

                    udpQuestions.Update();
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "NavigateQuestions()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }

        }

        protected void btnNext_Click(object sender, EventArgs e)
        {
            try
            {
                if (Session["currentQuestion"] != null && Session["QuestionsList"] != null)
                {
                    int nextQuestion = Convert.ToInt32(Session["currentQuestion"]) + 1;

                    Session["intNextQuestion"] = nextQuestion;
                    List<ExamInformation> lstQuestions = (List<ExamInformation>)Session["QuestionsList"];
                    string selectedOptions = rdbOptions != null ? rdbOptions.SelectedValue : GetSelectedOptionsFromChkOptions();
                    if (lstQuestions.Where(q => q.SerialNumber == (nextQuestion - 1)).Select(q => q.SelectedAnswer).FirstOrDefault() != selectedOptions)
                    {
                        //If Update needed then update the Answer to existing Question
                        SaveAnswer(lstQuestions, nextQuestion, 'N');
                    }
                    NavigateQuestions(lstQuestions, nextQuestion);
                    btnNext.Enabled = (nextQuestion == lstQuestions.Count()) ? false : true;
                    btnPrevious.Enabled = nextQuestion > 1 ? true : false;
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "btnNext_Click()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }
        }

        protected void btnPrevious_Click(object sender, EventArgs e)
        {
            try
            {
                if (Session["currentQuestion"] != null && Session["QuestionsList"] != null)
                {
                    //ClearControls();
                    int perviousQuestion = Convert.ToInt32(Session["currentQuestion"]) - 1;
                    Session["intNextQuestion"] = perviousQuestion;
                    List<ExamInformation> lstQuestions = (List<ExamInformation>)Session["QuestionsList"];
                    string selectedOptions = rdbOptions != null ? rdbOptions.SelectedValue : GetSelectedOptionsFromChkOptions();
                    if (lstQuestions.Where(q => q.SerialNumber == (perviousQuestion + 1)).Select(q => q.SelectedAnswer).FirstOrDefault() != selectedOptions)
                    {
                        //If Update needed then update the Answer to existing Question
                        SaveAnswer(lstQuestions, perviousQuestion, 'P');
                    }
                    NavigateQuestions(lstQuestions, perviousQuestion);
                    btnPrevious.Enabled = perviousQuestion < 2 ? false : true;
                    btnNext.Enabled = perviousQuestion < lstQuestions.Count() ? true : false;
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "btnPrevious_Click",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }

        }

        private void SaveAnswer(List<ExamInformation> lstQuestions, int questionNumber, char navigationType)
        {
            try
            {
                if (lstQuestions != null)
                {
                    int serialNumber = navigationType == 'P' ? questionNumber + 1 : questionNumber - 1;
                    ExamInformation examInfo = lstQuestions.Where(q => q.SerialNumber == serialNumber).FirstOrDefault();
                    if (examInfo != null)
                    {
                        examInfo.SelectedAnswer = examInfo.QuestionType == "S" ? rdbOptions.SelectedValue : GetSelectedOptionsFromChkOptions();

                        CommitAnswerInDB(examInfo);
                        Session["QuestionsList"] = lstQuestions;
                    }
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "SaveAnswer()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }


        }

        private string GetSelectedOptionsFromChkOptions()
        {
            string selectedOptions = string.Empty;
            for (int i = 0; i < chkOptions.Items.Count; i++)
            {
                if (chkOptions.Items[i].Selected)
                    selectedOptions += chkOptions.Items[i].Value + ",";
            }
            selectedOptions = selectedOptions.TrimEnd(',');
            return selectedOptions;
        }

        private void CommitAnswerInDB(ExamInformation examInfo)
        {
            try
            {
                if (Session["testId"] != null)
                {
                    int testId = Convert.ToInt32(Session["testId"]);
                    tempexam tempExamObject = TempExamLogic.GettempexamById(testId, examInfo.QuestionId);

                    if (tempExamObject == null)
                    {
                        tempExamObject = new tempexam()
                        {
                            TestId = testId,
                            QuestionId = examInfo.QuestionId,
                            SelectedAnswer = examInfo.SelectedAnswer,
                            OriginalAnswer = examInfo.OriginalAnswer,
                            IsResult = (string.Compare(examInfo.SelectedAnswer, examInfo.OriginalAnswer) == 0) ? true : false
                        };
                        TempExamLogic.InsertQuestionAnswer(tempExamObject);
                    }
                    else
                    {
                        if (tempExamObject.SelectedAnswer != examInfo.SelectedAnswer)
                        {
                            tempExamObject.SelectedAnswer = examInfo.SelectedAnswer;
                            tempExamObject.IsResult = (string.Compare(examInfo.SelectedAnswer, examInfo.OriginalAnswer) == 0) ? true : false;
                            TempExamLogic.UpdatetAnswer(tempExamObject);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "CommitAnswerInDB()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }
        }

        private void InsertUnAnsweredQuestions(List<ExamInformation> lstExamInfo)
        {
            try
            {
                if (Session["testId"] != null)
                {
                    int testId = Convert.ToInt32(Session["testId"]);
                    List<tempexam> lstTempExamObjects = new List<tempexam>();

                    if (lstExamInfo != null)
                    {
                        foreach (var item in lstExamInfo)
                        {
                            tempexam tempExamObject = new tempexam()
                            {
                                TestId = testId,
                                QuestionId = item.QuestionId,
                                SelectedAnswer = item.SelectedAnswer,
                                OriginalAnswer = item.OriginalAnswer,
                                IsResult = (string.Compare(item.SelectedAnswer, item.OriginalAnswer) == 0) ? true : false
                            };
                            lstTempExamObjects.Add(tempExamObject);
                        }

                        TempExamLogic.InsertUnAnsweredQuestions(lstTempExamObjects);
                    }
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "InsertUnAnsweredQuestions()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }
        }

        private void InsertExamResult(int testId)
        {
            try
            {
                if (testId > 0)
                {
                    List<tempexam> lsttempExamObjects = TempExamLogic.GetExamQuestionAndAnswersByTestId(testId);
                    if (lsttempExamObjects != null)
                    {

                        result resultObject = ResultLogic.GetResultById(testId);
                        resultObject.dateofendtest = DateTime.Now;

                        TimeSpan timeUtilized = new TimeSpan();
                        timeUtilized = (TimeSpan)(resultObject.dateofendtest - resultObject.dateofstarttest);

                        int obtainedMarks = 0;
                        foreach (var item in lsttempExamObjects)
                        {
                            if (string.Compare(item.SelectedAnswer, item.OriginalAnswer) == 0) obtainedMarks++;

                        }

                        decimal percentage = (100 * obtainedMarks) / lsttempExamObjects.Count;
                        decimal avgTimeSpentForQuestion = Convert.ToDecimal(lsttempExamObjects.Count / timeUtilized.TotalMinutes);

                        resultObject.marks = obtainedMarks.ToString();
                        resultObject.precentage = percentage.ToString();
                        resultObject.iscompleted = true;
                        resultObject.timeutilized = timeUtilized.TotalSeconds.ToString();
                        resultObject.agvtimeperquestion = avgTimeSpentForQuestion.ToString();

                        ResultLogic.UpdateResult(resultObject);
                        Session["ExamQuestionAndAnswers"] = lsttempExamObjects;
                    }

                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "InsertExamResult()",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }
        }

        protected void btnFinish_Click(object sender, EventArgs e)
        {
            try
            {
                if (Session["currentQuestion"] != null && Session["QuestionsList"] != null)
                {
                    int currentQuestion = Convert.ToInt32(Session["currentQuestion"]);
                    List<ExamInformation> lstQuestions = (List<ExamInformation>)Session["QuestionsList"];
                    ExamInformation examInfo = lstQuestions.Where(q => q.SerialNumber == currentQuestion).FirstOrDefault();
                    if (examInfo != null)
                    {
                        string selectedOptions = examInfo.QuestionType == "S" ? rdbOptions.SelectedValue : GetSelectedOptionsFromChkOptions();
                        if (examInfo.SelectedAnswer != selectedOptions)
                        {
                            examInfo.SelectedAnswer = selectedOptions;
                            CommitAnswerInDB(examInfo);
                            Session["QuestionsList"] = lstQuestions;
                        }

                    }

                    //for Unanswered questions insertion to DB
                    List<ExamInformation> lstUnAnswereQuestions = lstQuestions.Where(u => u.SelectedAnswer == null).ToList();
                    if (lstUnAnswereQuestions.Count > 0)
                    {
                        InsertUnAnsweredQuestions(lstUnAnswereQuestions);
                    }
                }
                if (Session["testId"] != null)
                {
                    int testId = Convert.ToInt32(Session["testId"]);
                    InsertExamResult(testId);
                    Session.Remove("examStart");
                    Session["examStart"] = null;
                    Response.Redirect("Result.aspx", false);
                }
            }
            catch (Exception ex)
            {
                acptest_ErrorLog errorLog = new acptest_ErrorLog()
                {
                    //ex.Message, "Page_Load", "Test Page"
                    ErrorMessage = ex.Message,
                    ErrorFunction = "btnFinish_Click",
                    InsertedTime = DateTime.Now,
                    ModuleName = "Test.aspx"
                };
                ACPErrorLogLogic.ErrorLog(errorLog);
            }
        }

    }
}